package com.onpositive.data;

import java.util.LinkedHashSet;

import com.onpositive.data.serializer.writers.AbstractWriter;

abstract public class AbstractReader<T> extends FilterTester {

	protected static final int DOUBLE_SIZE = 8;
	protected static final int INT_SIZE = 4;
	protected static final int CHAR_SIZE = 2;

	protected int myStart, myEnd, collectionStart;
	private boolean myStartInit = false, myEndInit = false,
			collectionStartInit = false, fileInit = false;
	private boolean initialized = false;

	protected ISeekableAccess file;

	protected Class<T> clazz;
	protected long bitmapInitTime = 0;
	protected long valuesArrayInitTime = 0;

	public AbstractReader(Class<T> clazz) // , int myStart, int myEnd, int
											// collectionStart, RandomAccessFile
											// file )
	{
		this.clazz = clazz;
	}
	
	public abstract AbstractWriter<T>getWriter();

	abstract public T getObject(int i);

	public final void init() {
		
		long l0=System.currentTimeMillis();
		if (!checkParams())
			this.reportError();

		doInit();

		this.setInitialized();
		long l1=System.currentTimeMillis();
		System.out.println("Init:"+(l1-l0));
	}

	abstract protected void doInit();

	public void setUninitialized() {
		this.initialized = false;
	}

	protected final void setInitialized() {
		this.initialized = true;
	}

	protected boolean checkParams() {
		return myStartInit && myEndInit && collectionStartInit && fileInit;
	}

	public Class<T> getClazz() {
		return clazz;
	}

	public int getMyStart() {
		return myStart;
	}

	public void setMyStart(int myStart) {
		this.myStart = myStart;
		myStartInit = true;
	}

	public int getMyEnd() {
		return myEnd;
	}

	public void setMyEnd(int myEnd) {
		this.myEnd = myEnd;
		myEndInit = true;
	}

	public int getCollectionStart() {
		return collectionStart;
	}

	public void setCollectionStart(int collectionStart) {
		this.collectionStart = collectionStart;
		collectionStartInit = true;
	}

	public ISeekableAccess getFile() {
		return file;
	}

	public void setFile(ISeekableAccess file) {
		this.file = file;
		fileInit = true;
	}

	protected boolean isInitialized() {
		return initialized;
	}

	protected void reportError() {

	}

	public long getBitmapInitTime() {
		return bitmapInitTime;
	}

	public long getValuesArrayInitTime() {
		return valuesArrayInitTime;
	}

	public abstract void filterOut(LinkedHashSet<Object> obj, String text);

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public int compare(int num, int num2) {

		Comparable object = (Comparable) getObject(num);
		Comparable object1 = (Comparable) getObject(num2);
		if (object != null) {
			if (object1==null){
				return 1;
			}
			return object.compareTo(object1);
		}
		if (object1 != null) {			
			return -1;
		}
		return 0;
	}

	public abstract void setValue(int num, Object value) ;

	public abstract void initEmpty(int dataSize);
	
	public abstract void expand(int newSize);
}
